﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms; // 需要添加 System.Windows.Forms 的引用
using System.Drawing;      // 需要添加 System.Drawing 的引用

// Revit API 命名空间
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical; // Space 类在这里
using Autodesk.Revit.DB.Analysis;   // HVACLoadSpaceType 类在这里
using Autodesk.Revit.UI;
using Autodesk.Revit.Attributes;

// --- 使用别名避免冲突 ---
using WinForms = System.Windows.Forms;
using Drawing = System.Drawing;

namespace RevitProject.SpaceManager.Commands // 请确保使用您项目正确的命名空间
{
    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class SPTestDeleteSpaceTypesCommand : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;

            // --- 1. 获取所有空间类型 ---
            var allSpaceTypes = new FilteredElementCollector(doc)
                .OfClass(typeof(HVACLoadSpaceType))
                .Cast<HVACLoadSpaceType>()
                .OrderBy(st => st.Name)
                .ToList();

            if (!allSpaceTypes.Any())
            {
                TaskDialog.Show("信息", "项目中没有找到任何 HVAC 空间类型可供删除。");
                return Result.Succeeded;
            }

            // --- 2. 检查哪些类型正在使用 ---
            var usedSpaceTypeIds = new HashSet<ElementId>();

            // --- 修改开始 ---
            // 先过滤 SpatialElement，然后在内存中筛选出 Space 类型
            var allSpaces = new FilteredElementCollector(doc)
                .OfClass(typeof(SpatialElement)) // 使用基类过滤
                .OfType<Space>()                 // 使用 LINQ 的 OfType 筛选出 Space
                .ToList();
            // --- 修改结束 ---


            foreach (var space in allSpaces)
            {
                // 检查 SpaceTypeId 是否有效
                if (space.SpaceTypeId != null && space.SpaceTypeId != ElementId.InvalidElementId)
                {
                    usedSpaceTypeIds.Add(space.SpaceTypeId);
                }
            }

            // --- 3. 显示选择窗口 ---
            List<ElementId> typesToDeleteIds = new List<ElementId>();
            using (var form = new SelectSpaceTypesToDeleteForm(allSpaceTypes, usedSpaceTypeIds))
            {
                if (form.ShowDialog() == WinForms.DialogResult.OK)
                {
                    typesToDeleteIds = form.GetSelectedTypeIds();
                }
                else
                {
                    return Result.Cancelled; // 用户取消
                }
            }

            if (!typesToDeleteIds.Any())
            {
                TaskDialog.Show("信息", "没有选择任何空间类型进行删除。");
                return Result.Succeeded;
            }

            // --- 4. 确认删除 ---
            StringBuilder confirmationMessage = new StringBuilder("确定要删除以下空间类型吗？\n");
            int count = 0;
            foreach (ElementId id in typesToDeleteIds)
            {
                var type = doc.GetElement(id) as HVACLoadSpaceType;
                if (type != null)
                {
                    confirmationMessage.AppendLine($"- {type.Name} (ID: {id.IntegerValue})");
                    count++;
                }
            }
            confirmationMessage.Append($"\n总计：{count} 个类型。此操作无法撤销！");

            TaskDialog confirmDialog = new TaskDialog("确认删除");
            confirmDialog.MainInstruction = "确认删除空间类型";
            confirmDialog.MainContent = confirmationMessage.ToString();
            confirmDialog.CommonButtons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel;
            confirmDialog.DefaultButton = TaskDialogResult.Cancel;

            if (confirmDialog.Show() != TaskDialogResult.Ok)
            {
                return Result.Cancelled;
            }

            // --- 5. 执行删除 ---
            int deletedCount = 0;
            int errorCount = 0;
            StringBuilder resultsLog = new StringBuilder();

            using (Transaction tx = new Transaction(doc, "删除空间类型"))
            {
                tx.Start();
                try
                {
                    foreach (ElementId id in typesToDeleteIds)
                    {
                        // 再次检查是否仍在使用（以防万一）
                        if (usedSpaceTypeIds.Contains(id))
                        {
                            var type = doc.GetElement(id) as HVACLoadSpaceType;
                            resultsLog.AppendLine($"跳过: 类型 '{type?.Name ?? id.ToString()}' 因为正在被使用。");
                            errorCount++;
                            continue;
                        }

                        // 尝试删除
                        try
                        {
                            doc.Delete(id);
                            deletedCount++;
                            // 无需记录成功日志，除非需要详细信息
                            // var type = doc.GetElement(id); // 获取不到已删除的名称了
                            // resultsLog.AppendLine($"成功: 删除了 ID 为 {id.IntegerValue} 的类型。");
                        }
                        catch (Exception ex)
                        {
                            var type = doc.GetElement(id); // 尝试在错误时获取名称
                            resultsLog.AppendLine($"错误: 删除类型 '{type?.Name ?? id.ToString()}' 时失败: {ex.Message}");
                            errorCount++;
                        }
                    }

                    if (errorCount > 0 && deletedCount == 0) // 如果有错误且没有任何成功删除
                    {
                        tx.RollBack(); // 回滚事务
                        TaskDialog.Show("删除失败", $"未能删除任何选定的空间类型。\n\n详细信息:\n{resultsLog}");
                        return Result.Failed;
                    }
                    else
                    {
                        tx.Commit();
                    }
                }
                catch (Exception ex)
                {
                    tx.RollBack();
                    message = $"执行删除操作时发生严重错误: {ex.Message}";
                    TaskDialog.Show("错误", message + "\n\n详细日志:\n" + resultsLog.ToString());
                    return Result.Failed;
                }
            }

            // --- 6. 显示结果 ---
            TaskDialog resultDialog = new TaskDialog("删除结果");
            resultDialog.MainInstruction = $"操作完成。成功删除了 {deletedCount} 个空间类型。";
            if (errorCount > 0 || resultsLog.Length > 0)
            {
                resultDialog.MainContent = $"有 {errorCount} 个类型未能删除。";
                resultDialog.ExpandedContent = resultsLog.ToString();
            }
            resultDialog.CommonButtons = TaskDialogCommonButtons.Ok;
            resultDialog.Show();

            return Result.Succeeded;
        }
    }

    /// <summary>
    /// 用于选择要删除的空间类型的 Windows Form
    /// </summary>
    public class SelectSpaceTypesToDeleteForm : WinForms.Form
    {
        private WinForms.CheckedListBox checkedListBoxTypes;
        private WinForms.Button buttonOk;
        private WinForms.Button buttonCancel;
        private WinForms.Label labelInstruction;
        private List<HVACLoadSpaceType> _allTypes;
        private HashSet<ElementId> _usedTypeIds;
        private WinForms.Button buttonSelectAll; // 新增：全选按钮
        private WinForms.Button buttonSelectNone; // 新增：全不选按钮
        public SelectSpaceTypesToDeleteForm(List<HVACLoadSpaceType> allTypes, HashSet<ElementId> usedTypeIds)
        {
            _allTypes = allTypes;
            _usedTypeIds = usedTypeIds;
            InitializeComponent();
            PopulateList(allTypes);
        }

        private void InitializeComponent()
        {
            // 实例化现有控件
            this.checkedListBoxTypes = new WinForms.CheckedListBox();
            this.buttonOk = new WinForms.Button();
            this.buttonCancel = new WinForms.Button();
            this.labelInstruction = new WinForms.Label();
            // 实例化新按钮
            this.buttonSelectAll = new WinForms.Button();
            this.buttonSelectNone = new WinForms.Button();
            this.SuspendLayout();

            // labelInstruction (属性不变)
            this.labelInstruction.AutoSize = true;
            this.labelInstruction.Location = new Drawing.Point(12, 9);
            this.labelInstruction.Name = "labelInstruction";
            this.labelInstruction.Size = new Drawing.Size(269, 13); // 可能需要调整以适应更宽的文本
            this.labelInstruction.TabIndex = 0;
            this.labelInstruction.Text = "请勾选要删除的空间类型（灰色项表示正在使用，无法删除）:";

            // checkedListBoxTypes (调整底部锚点或大小以适应新按钮)
            this.checkedListBoxTypes.Anchor = ((WinForms.AnchorStyles)((((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Bottom)
            | WinForms.AnchorStyles.Left)
            | WinForms.AnchorStyles.Right)));
            this.checkedListBoxTypes.FormattingEnabled = true;
            this.checkedListBoxTypes.CheckOnClick = true;
            this.checkedListBoxTypes.Location = new Drawing.Point(15, 28);
            this.checkedListBoxTypes.Name = "checkedListBoxTypes";
            // 稍微缩小一点高度给按钮留空间，或者保持原样看效果
            this.checkedListBoxTypes.Size = new Drawing.Size(357, 184);
            this.checkedListBoxTypes.TabIndex = 1;
            this.checkedListBoxTypes.ItemCheck += CheckedListBoxTypes_ItemCheck;

            // buttonOk (位置不变)
            this.buttonOk.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Right)));
            this.buttonOk.DialogResult = WinForms.DialogResult.OK;
            this.buttonOk.Location = new Drawing.Point(216, 226);
            this.buttonOk.Name = "buttonOk";
            this.buttonOk.Size = new Drawing.Size(75, 23);
            this.buttonOk.TabIndex = 2;
            this.buttonOk.Text = "确定";
            this.buttonOk.UseVisualStyleBackColor = true;
            this.buttonOk.Click += (sender, e) => { this.DialogResult = WinForms.DialogResult.OK; };

            // buttonCancel (位置不变)
            this.buttonCancel.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Right)));
            this.buttonCancel.DialogResult = WinForms.DialogResult.Cancel;
            this.buttonCancel.Location = new Drawing.Point(297, 226);
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new Drawing.Size(75, 23);
            this.buttonCancel.TabIndex = 3;
            this.buttonCancel.Text = "取消";
            this.buttonCancel.UseVisualStyleBackColor = true;
            this.buttonCancel.Click += (sender, e) => { this.DialogResult = WinForms.DialogResult.Cancel; };

            // buttonSelectAll (新按钮 - 放置在左下角)
            this.buttonSelectAll.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Left)));
            this.buttonSelectAll.Location = new Drawing.Point(15, 226); // 与确定/取消按钮底部对齐
            this.buttonSelectAll.Name = "buttonSelectAll";
            this.buttonSelectAll.Size = new Drawing.Size(75, 23);
            this.buttonSelectAll.TabIndex = 4; // 下一个 TabIndex
            this.buttonSelectAll.Text = "全选";
            this.buttonSelectAll.UseVisualStyleBackColor = true;
            this.buttonSelectAll.Click += new System.EventHandler(this.ButtonSelectAll_Click); // 绑定事件

            // buttonSelectNone (新按钮 - 放置在全选旁边)
            this.buttonSelectNone.Anchor = ((WinForms.AnchorStyles)((WinForms.AnchorStyles.Bottom | WinForms.AnchorStyles.Left)));
            this.buttonSelectNone.Location = new Drawing.Point(96, 226); // 放置在全选按钮右侧
            this.buttonSelectNone.Name = "buttonSelectNone";
            this.buttonSelectNone.Size = new Drawing.Size(75, 23);
            this.buttonSelectNone.TabIndex = 5; // 再下一个 TabIndex
            this.buttonSelectNone.Text = "全不选";
            this.buttonSelectNone.UseVisualStyleBackColor = true;
            this.buttonSelectNone.Click += new System.EventHandler(this.ButtonSelectNone_Click); // 绑定事件

            // SelectSpaceTypesToDeleteForm (窗体设置)
            this.AcceptButton = this.buttonOk;
            this.CancelButton = this.buttonCancel;
            this.ClientSize = new Drawing.Size(384, 261); // 尺寸通常不需要改变
            this.Controls.Add(this.labelInstruction);
            this.Controls.Add(this.checkedListBoxTypes);
            this.Controls.Add(this.buttonOk);
            this.Controls.Add(this.buttonCancel);
            this.Controls.Add(this.buttonSelectAll);  // 将新按钮添加到窗体控件中
            this.Controls.Add(this.buttonSelectNone); // 将新按钮添加到窗体控件中
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.MinimumSize = new Drawing.Size(350, 250);
            this.Name = "SelectSpaceTypesToDeleteForm";
            this.ShowIcon = false;
            this.ShowInTaskbar = false;
            this.StartPosition = WinForms.FormStartPosition.CenterParent;
            this.Text = "选择要删除的空间类型";
            this.ResumeLayout(false);
            this.PerformLayout();
        }


        // 全选按钮的点击事件处理
        private void ButtonSelectAll_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < checkedListBoxTypes.Items.Count; i++)
            {
                string itemText = checkedListBoxTypes.Items[i].ToString();
                // 仅勾选那些不是“正在使用”的项
                if (!itemText.EndsWith(" - [正在使用]"))
                {
                    checkedListBoxTypes.SetItemChecked(i, true);
                }
            }
        }

        // 全不选按钮的点击事件处理
        private void ButtonSelectNone_Click(object sender, EventArgs e)
        {
            // 遍历所有项并取消勾选
            for (int i = 0; i < checkedListBoxTypes.Items.Count; i++)
            {
                checkedListBoxTypes.SetItemChecked(i, false);
            }
            // 或者使用这种方式清空所有勾选:
            // while (checkedListBoxTypes.CheckedIndices.Count > 0)
            // {
            //     checkedListBoxTypes.SetItemChecked(checkedListBoxTypes.CheckedIndices[0], false);
            // }
        }

        private void PopulateList(List<HVACLoadSpaceType> allTypes) // 接收类型列表作为参数
        {
            checkedListBoxTypes.Items.Clear();
            foreach (var type in allTypes)
            {
                bool isUsed = _usedTypeIds.Contains(type.Id);
                // 格式化要显示的字符串 (Name 属性应该包含中文名称)
                string displayText = $"{type.Name} (ID: {type.Id.IntegerValue}){(isUsed ? " - [正在使用]" : "")}";

                // 直接添加格式化后的字符串
                checkedListBoxTypes.Items.Add(displayText, false); // 添加字符串，默认不选中
            }
        }

        // 事件处理：阻止用户勾选标记为“正在使用”的项
        private void CheckedListBoxTypes_ItemCheck(object sender, WinForms.ItemCheckEventArgs e)
        {
            if (e.Index >= 0 && e.Index < checkedListBoxTypes.Items.Count)
            {
                // 获取当前项的显示文本
                string itemText = checkedListBoxTypes.Items[e.Index].ToString();
                // 检查文本是否表示该项正在使用
                if (itemText.EndsWith(" - [正在使用]"))
                {
                    // 如果是正在使用的项，则阻止用户勾选它
                    e.NewValue = CheckState.Unchecked;
                }
            }
        }


        public List<ElementId> GetSelectedTypeIds()
        {
            List<ElementId> selectedIds = new List<ElementId>();
            // 遍历所有被勾选的项
            foreach (object item in checkedListBoxTypes.CheckedItems)
            {
                string itemText = item.ToString();
                // 再次确认这个项不是标记为“正在使用”的（以防万一）
                if (!itemText.EndsWith(" - [正在使用]"))
                {
                    // 从类似 "会议室 (ID: 12345)" 的字符串中解析出 ID
                    int idStartIndex = itemText.LastIndexOf("(ID: ");
                    int idEndIndex = itemText.LastIndexOf(")");
                    if (idStartIndex != -1 && idEndIndex > idStartIndex)
                    {
                        // 提取 ID 数字部分的字符串
                        string idString = itemText.Substring(idStartIndex + 5, idEndIndex - (idStartIndex + 5)).Trim();
                        // 尝试将字符串解析为整数
                        if (int.TryParse(idString, out int idValue))
                        {
                            // 根据整数值创建 ElementId
                            // 注意：对于非常大的 ID，可能需要 long.TryParse 和 new ElementId(long idValue)，
                            // 但对于大多数情况，int 足够。请根据您的 Revit 版本和项目情况调整。
#if REVIT2016 || REVIT2017 || REVIT2018 || REVIT2019 || REVIT2020 || REVIT2021 || REVIT2022 || REVIT2023 || REVIT2024
                         selectedIds.Add(new ElementId(idValue));
#else
                            // 假设是 Revit 2025 或更高版本，可能需要 long 型构造函数
                            // 如果 ElementId(int) 仍然可用，则下面这行也适用
                            selectedIds.Add(new ElementId(idValue));
#endif
                        }
                        else
                        {
                            // 如果解析失败，可以记录日志或忽略
                            Console.WriteLine($"无法从字符串 '{itemText}' 中解析 ID。");
                        }
                    }
                }
            }
            return selectedIds;
        }
    }
}